<script lang="ts" setup>
import type { PropType, WritableComputedRef } from "vue";
import { componentList as components } from "../components/config";
import { newRandomUid, deepClone, debounce } from "@/utils";
import nestedDraggable from "./components/NestedDraggable.vue";
import ActComponentRender from "./components/ActComponentRender.vue";
import MyComponets from "../activityTemplate/MyComponets.vue";
import ImportComponentsDialog from "../activityTemplate/ImportComponentsDialog.vue";
const props = defineProps({
  modelValue: {
    type: Array as PropType<Array<any>>,
    default: () => {
      return [];
    },
  },
  original: {
    type: String,
    default: "",
  },
  actType: {
    type: [String, Number],
    default: 1,
  },
  pageList: {
    type: Array as PropType<Array<any>>,
    default: () => {
      return [];
    },
  },
});

const emits = defineEmits(["change", "update:modelValue", "import", "refresh", "refreshRegionConfig"]);
const modelValueModel: WritableComputedRef<any> = computed({
  get() {
    return props.modelValue ?? [];
  },
  set(newValue) {
    emits("update:modelValue", newValue);
    emits("change");
  }
})
const tabIndex = ref(""),
  showDrawer = ref(false),
  componentList = ref<Array<any>>(components),
  componentParent = ref(),
  importConfigDialog = ref(false),
  importConfigForm = ref<any>({ name: "", icon: "" });

const componentRef = ref<any>(),
  myComponentRef = ref();

watch(
  tabIndex,
  (newTab, oldTab) => {
    nextTick(() => {
      changeTab(newTab, oldTab);
    });
  },
  { immediate: true }
);

const winnerPopupList = computed(() => {
  return modelValueModel.value.filter(
    (item) => item.type === "Popup" && item.pageConfig.type === "winnerPrize"
  );
});

const receivePopupList = computed(() => {
  return modelValueModel.value.filter(
    (item) =>
      item.type === "CustomPopup" &&
      item.children &&
      item.children.find((child: any) => child.type === "PrizeReceive")
  );
});

const thanksPopupList = computed(() => {
  return modelValueModel.value.filter(
    (item) => item.type === "Popup" && item.pageConfig.type === "thanksPrize"
  );
});

const popupList = computed(() => {
  return modelValueModel.value.filter(
    (item) => item.type === "Popup" || item.pageConfig.$mode === "popup"
  );
});

const pageList = computed(() => {
  return props.pageList;
});

const changeTab = (newTab: string, oldTab: string | undefined) => {
  let { parent: oldComponent = null } = oldTab ? getElementByUid(oldTab) : {};
  let { parent: newComponent } = getElementByUid(newTab);
  if (
    oldTab !== undefined &&
    oldComponent &&
    (oldComponent.type === "Popup" || oldComponent.pageConfig.$mode === "popup")
  ) {
    oldComponent.pageConfig.$show = false;
    emits("change");
  }
  if (
    newComponent &&
    (newComponent.type === "Popup" || newComponent.pageConfig.$mode === "popup")
  ) {
    newComponent.pageConfig.$show = true;
    emits("change");
  }
};

// 通过uid查找组件
const getElementByUid = (uid: string) => {
  let element = null,
    elementIndex: Array<number> = [],
    parent = null;
  for (let i = 0; i < modelValueModel.value.length; i++) {
    if (modelValueModel.value[i].uid === uid) {
      parent = modelValueModel.value[i];
      element = modelValueModel.value[i];
      elementIndex = [i];
      break;
    }
    let children = modelValueModel.value[i].children || [];
    for (let j = 0; j < children.length; j++) {
      if (children[j].uid === uid) {
        parent = modelValueModel.value[i];
        element = children[j];
        elementIndex = [i, j];
        break;
      }
    }
  }
  return { element, elementIndex, parent };
};

const showPopupDrawer = (parent?: any) => {
  if (parent) {
    for (let i = 0; i < components.length; i++) {
      for (let j = 0; j < components[i].components.length; j++) {
        let component: any = components[i].components[j];
        if (component.type === parent.type) {
          componentList.value = component.components;
        }
      }
    }
    componentParent.value = parent;
  } else {
    if (props.original === "merchant") {
      let baseComponents = components.map((group) => {
        return {
          name: group.name,
          components: group.components.filter((item) => !item.zone),
        };
      });
      componentList.value = baseComponents.filter(
        (item) => item.components.length > 0
      );
    } else componentList.value = components;
    componentParent.value = null;
  }
  showDrawer.value = true;
};

const autoSorting = debounce(
  () => {
    // 页面背景/普通组件/置底组件/弹窗
    let background = null,
      popup = [],
      preOridinary = [],
      afterOrdinary = [],
      vote = null;
    let voteIndex = modelValueModel.value.findIndex(
      (item) => item.type === "VoteOnly"
    );
    vote = modelValueModel.value[voteIndex];
    for (let i = 0; i < modelValueModel.value.length; i++) {
      if (i === voteIndex) continue;
      let type = modelValueModel.value[i].type;
      let positionType = modelValueModel.value[i].pageConfig.$positionType;
      if (type === "Popup") popup.push(modelValueModel.value[i]);
      else if (type === "Background") background = modelValueModel.value[i];
      else if (i < voteIndex) preOridinary.push(modelValueModel.value[i]);
      else if (positionType === "relative" || !positionType)
        preOridinary.push(modelValueModel.value[i]);
      else if (i > voteIndex) afterOrdinary.push(modelValueModel.value[i]);
    }

    emits(
      "update:modelValue",
      [background]
        .concat(preOridinary)
        .concat(vote ? [vote] : [])
        .concat(afterOrdinary)
        .concat(popup)
    );
    emits("change");
  },
  300,
  false
);

const openTab = (uid: string) => {
  tabIndex.value = uid;
};

const onDelete = (uid: any) => {
  let { element, elementIndex } = getElementByUid(uid);
  ElMessageBox.confirm(`确定删除${element.name}吗？`, "温馨提示", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  }).then(async () => {
    // try {
    await componentRef.value.remove(uid);
    ({ element, elementIndex } = getElementByUid(uid));
    // 删除配置项
    console.log('[  getElementByUid(uid)) ]', getElementByUid(uid))
    if (elementIndex.length == 1) {
      modelValueModel.value.splice(elementIndex[0], 1);
      if (uid == tabIndex.value) {
        openTab(modelValueModel.value[elementIndex[0] - 1].uid);
      }
    } else if (elementIndex.length == 2) {
      modelValueModel.value[elementIndex[0]].children.splice(elementIndex[1], 1);
      if (uid == tabIndex.value) {
        openTab(
          modelValueModel.value[elementIndex[0]].children[elementIndex[1] - 1].uid
        );
      }
    }
    autoSorting();
    // } catch (e) {
    // if (e) {
    //   ElNotification.error({
    //     message: e || "移除失败",
    //   } as any);
    // }
    // }
  });
};

const onExpand = (index: number) => {
  componentList.value[index].fold = !componentList.value[index].fold;
};

const addComponent = (component: any, config = {}, open = true) => {
  console.log('[ component ]', component)
  console.log('[ config ]', config)

  let { type, name, group = false } = component;
  if (!type) {
    ElMessage({
      message: "暂未上线该组件，敬请期待",
      type: "warning",
    });
    return;
  }
  showDrawer.value = false;
  let uid = newRandomUid();
  let list = modelValueModel.value;
  if (componentParent.value) {
    list = componentParent.value.children;
  }

  let configData: any = deepClone(config)
  console.log('[ configData ]', configData)
  if (configData.children && configData.children.length) {
    configData.children.forEach((item: any) => {
      item.uid = newRandomUid()
    })
  }

  if (!configData.pageConfig) {
    configData.pageConfig = {}
  }
  if (configData.type) {
    configData.pageConfig.$pageFlag = `${configData.type}-${newRandomUid()}`
  }
  //自定义弹框
  if(component.type=='CustomPopup'){
    configData.$autoShow=0
    configData.$frequency=1
  }

  list.push({
    type,
    group,
    pageConfig: {},
    ...configData,
    uid,
    name,
  });
  console.log('[ uid ]', uid)
  console.log('[ list ]', list)

  if (open) openTab(uid);
  autoSorting();
  emits("refreshRegionConfig", uid)
  return uid;
};

// 导出配置
const importConfig = ($el: any) => {
  editComponent({ name: $el.name, comConfig: JSON.stringify($el), icon: "" });
};

// 刷新我的组件
const getMyComponent = () => {
  // if( myComponentRef.value){
  //   myComponentRef.value.refresh();
  //   return
  // } 
  emits("refresh");
};

// 编辑组件配置
const editComponent = (val?: any) => {
  if (val) {
    importConfigForm.value = val;
  }
  importConfigDialog.value = true;
};

const onChange = () => {
  emits("update:modelValue", modelValueModel.value);
  emits("change");
};

const submit = () => {
  return new Promise(async (resolve, reject) => {
    try {

      await componentRef.value.check();
    } catch (e: any) {
      if (e.uid) tabIndex.value = e.uid;
      reject(e.message || e);
    }
    resolve(modelValueModel.value);
  });
};

provide("winnerPopupList", winnerPopupList);
provide("receivePopupList", receivePopupList);
provide("thanksPopupList", thanksPopupList);
provide("popupList", popupList);
provide("original", props.original);
provide("pageList", pageList);
provide("addComponent", addComponent);
provide("deleteComponent", onDelete);
provide("showDrawer", showPopupDrawer);
provide("importConfig", importConfig);
provide("changeTab", changeTab);
provide("autoSorting", autoSorting);

onMounted(() => {
  if (props.original === "merchant") {
    let baseComponents = components.map((group) => {
      return {
        name: group.name,
        components: group.components.filter((item) => !item.zone),
      };
    });
    componentList.value = baseComponents.filter(
      (item) => item.components.length > 0
    );
  }
  if (modelValueModel.value && modelValueModel.value[0]) openTab(modelValueModel.value[0].uid);
});

defineExpose({ submit, delete: onDelete, jumpTo: openTab });
</script>
<template>
  <div class="config-container">
    <div class="sort-container">
      <nested-draggable v-model="modelValueModel" v-model:select="tabIndex" @change="onChange" />
    </div>
    <div class="container">
      <ActComponentRender ref="componentRef" v-model:model-value="modelValueModel" :select="tabIndex"
        @change="onChange" />
    </div>
  </div>
  <el-drawer v-model="showDrawer" title="添加组件" direction="rtl" append-to-body @close="componentParent = null">
    <div class="component-list">
      <div class="component-group" v-for="(group, gIndex) in componentList">
        <div class="component-group_title">
          <span>{{ group.name }}</span>
          <el-button color="#999999" link @click="onExpand(gIndex)">{{
            group.fold ? "展开" : "收起"
          }}</el-button>
        </div>
        <Transition name="expand">
          <div v-show="!group.fold" class="component-group_el">
            <template v-for="item in group.components">
              <div v-if="item.type" class="component-group_el-item" @click="addComponent(item)">
                <img :src="item.icon" alt="" />
                <div>{{ item.name }}</div>
              </div>
            </template>
          </div>
        </Transition>
      </div>
      <!-- 我的组件 -->
      <!-- <MyComponets
        ref="myComponentRef"
        @edit="editComponent"
        @add="addComponent"
      /> -->
    </div>
  </el-drawer>
  <ImportComponentsDialog v-model:form="importConfigForm" v-model:show="importConfigDialog" @save="getMyComponent" />
</template>
<style lang="scss" scoped>
.config-container {
  display: flex;
  overflow: hidden;
}

.sort-container {
  height: 100%;
  overflow-x: hidden;
  flex-shrink: 0;
  width: 120px;
  position: relative;
  z-index: 999;

  >div {
    height: 100%;
    width: 126px;
    overflow-y: auto;
  }
}

.container {
  height: 100%;
  overflow-y: auto;
  flex: 1;
  margin-left: 10px;
  min-width: 450px;
}

.component-list {
  .component-group_title {
    padding: 8px 12px;
    background-color: #f7f7fa;
    display: flex;
    justify-content: space-between;
  }

  .component-group_el {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    padding: 10px;

    &-item {
      width: 76px;
      height: 76px;
      border: 1px solid transparent;
      border-radius: 5px;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      align-items: center;
      font-size: 14px;
      cursor: pointer;

      img {
        display: block;
        width: 38px;
        height: 57px;
        object-fit: contain;
      }

      &:hover {
        border-color: #fb6638;
      }
    }
  }
}
</style>
